/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.DemoKit;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.google.android.DemoKit.R;
import com.hethongviet.vending.model.Transaction;
import com.hethongviet.vending.pages.GeneralActivity;

import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;

//import com.android.future.usb.UsbAccessory;
//import com.android.future.usb.UsbManager;

import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;

public class DemoKitActivity extends GeneralActivity implements Runnable
{
	private static final String TAG = "DemoKit";

	private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION";

	private UsbManager mUsbManager;
	private PendingIntent mPermissionIntent;
	private boolean mPermissionRequestPending;

	UsbAccessory mAccessory;
	ParcelFileDescriptor mFileDescriptor;
	FileInputStream mInputStream;
	FileOutputStream mOutputStream;

	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
	{
		@Override
		public void onReceive(Context context, Intent intent)
		{
			String action = intent.getAction();
			debugToastUsb("received receiver, action = " + action);
			if (ACTION_USB_PERMISSION.equals(action))
			{
				synchronized (this)
				{
					UsbAccessory accessory = getAccessory(intent);
					if (intent.getBooleanExtra(
							UsbManager.EXTRA_PERMISSION_GRANTED, false))
					{
						debugToastUsb("Open USB port");
						openAccessory(accessory);
					}
					else
					{
						debugToastUsb("Can not open USB Port");
						debug("permission denied for accessory " + accessory);
					}
					mPermissionRequestPending = false;
				}
			}
			else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
			{
				UsbAccessory accessory = getAccessory(intent);
				if (accessory != null && accessory.equals(mAccessory))
				{
					debugToastUsb("close USB port");
					closeAccessory();
				}
			}
		}
	};

	private UsbAccessory getAccessory(Intent intent)
	{
		// return UsbManager.getAccessory(intent); USE API : android 2.3
		return (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		// mUsbManager = UsbManager.getInstance(this);
		mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

		try
		{
			openFileInput("usb");
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
				ACTION_USB_PERMISSION), 0);

		IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
		filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);

		registerReceiver(mUsbReceiver, filter);

		Object object = getLastNonConfigurationInstance();
		debugToastUsb("getLastNonConfigurationInstance() = " + object);
		if (object != null)
		{
			mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
			debugToastUsb("mAccessory = " + mAccessory);
			openAccessory(mAccessory);
		}

		setContentView(R.layout.page_standby);
	}

	@Override
	public Object onRetainNonConfigurationInstance()
	{
		if (mAccessory != null)
		{
			return mAccessory;
		}
		else
		{
			return super.onRetainNonConfigurationInstance();
		}
	}

	@Override
	public void onResume()
	{
		super.onResume();

		if (mInputStream != null && mOutputStream != null)
		{
			return;
		}

		UsbAccessory[] accessories = mUsbManager.getAccessoryList();
		UsbAccessory accessory = (accessories == null ? null : accessories[0]);
		if (accessory != null)
		{
			if (mUsbManager.hasPermission(accessory))
			{
				openAccessory(accessory);
			}
			else
			{
				synchronized (mUsbReceiver)
				{
					if (!mPermissionRequestPending)
					{
						mUsbManager.requestPermission(accessory,
								mPermissionIntent);
						mPermissionRequestPending = true;
					}
				}
			}
		}
		else
		{
			Log.d(TAG, "mAccessory is null");
		}
	}

	@Override
	public void onPause()
	{
		super.onPause();
		closeAccessory();
	}

	@Override
	public void onDestroy()
	{
		unregisterReceiver(mUsbReceiver);
		super.onDestroy();
	}

	private void openAccessory(UsbAccessory accessory)
	{
		try
		{
			mFileDescriptor = mUsbManager.openAccessory(accessory);
		} catch (Exception e)
		{
			e.printStackTrace();
			debugToastUsb("create mFileDescriptor fail" + e.getMessage());
			return;
		}

		debugToastUsb("mFileDescriptor = " + mFileDescriptor);
		if (mFileDescriptor != null)
		{
			debugToastUsb("accessory opening ");
			mAccessory = accessory;
			FileDescriptor fd = mFileDescriptor.getFileDescriptor();
			mInputStream = new FileInputStream(fd);
			mOutputStream = new FileOutputStream(fd);

			debugToastUsb("mInputStream = " + mInputStream);
			debugToastUsb("mOutputStream = " + mOutputStream);

			Thread thread = new Thread(null, this, getClass().getName());

			thread.start();

			debugToastUsb("accessory opened");

		}
		else
		{
			Log.d(TAG, "accessory open fail");
		}
	}

	private void closeAccessory()
	{
		try
		{
			if (mFileDescriptor != null)
			{
				mFileDescriptor.close();
			}
		} catch (IOException e)
		{
			debugToastUsb("close mFileDescriptor fail" + e.getMessage());
		} finally
		{
			mFileDescriptor = null;
			mAccessory = null;
		}
	}

	public void run()
	{
		int ret = 0;
		byte[] buffer = new byte[16384];

		while (ret >= 0)
		{
			try
			{
				ret = mInputStream.read(buffer);
				
				Message m = Message.obtain(mHandler, 1);
				m.obj = new String(buffer);
				mHandler.sendMessage(m);
				
			} catch (IOException e)
			{
				e.printStackTrace();
				break;
			}
		}
	}

	Handler mHandler = new Handler()
	{
		@Override
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
				case 1:
					onReceivedUsbMessage((String) msg.obj);
					break;

			}
		}
	};

	public void sendCommand(byte command, byte target1, byte target2)
	{
		debugToastUsb("send messsage = " + command + ", " + target1 + ", "
				+ target2);

		byte[] buffer = new byte[3];
		// if (value > 255)
		// value = 255;

		buffer[0] = command;
		buffer[1] = target1;
		buffer[2] = target2;
		if (mOutputStream != null && buffer[1] != -1)
		{
			try
			{
				mOutputStream.write(buffer);
			} catch (Exception e)
			{
				debugToastUsb("write failed" + e.getMessage());
			}
		}
	}

	public void debugToastUsb(String message)
	{
		Toast.makeText(this, message, Toast.LENGTH_LONG).show();
	}

	public void usbSend(String message)
	{
		debugToastUsb("Send message = " + message);

		if (mOutputStream == null)
		{
			debugToastUsb("Output stream is not available");
			return;
		}

		try
		{
			mOutputStream.write(message.getBytes());
			debugToastUsb("Message USB sent");
		} catch (Exception e)
		{
			e.printStackTrace();

			debugToastUsb("Send fail!!" + e.getMessage());
		}
	}

	@Override
	public void onConnectFail(int typeError)
	{
	}

	@Override
	public void onNetworkMessageIncomming(Transaction transaction)
	{
	}

	public void onReceivedUsbMessage(String message)
	{
	}
}
